<template>
  <div class="app-container">
    <el-container>
      <el-header height="40px" class="header-wrapper">
        <div class="breadcrumb">
          <el-breadcrumb separator-icon="ArrowRight">
            <el-breadcrumb-item v-for="node in nodes">
              <el-button link @click="handleNodeClick(node)" v-if="!node.virtual">
                {{ node.name }}
              </el-button>
              <el-text v-else type="info">{{ node.name }}</el-text>
            </el-breadcrumb-item>
          </el-breadcrumb>
        </div>
        <div class="input">
          <el-input v-model="queryParams.keyword" :placeholder="`搜索 '${currentNode.name}' '`" clearable
            prefix-icon="Search" @keydown.enter="handleAllSearch"></el-input>
        </div>
      </el-header>
      <el-container class="content-wrapper">
        <el-container v-loading="loading" class="zone" :class="{ active: isDragging }" @contextmenu.stop="onContextMenu"
          @dragenter.prevent="onDragEnter" @dragover.prevent="onDragOver" @dragleave="onDragLeave"
          @drop.prevent="onDrop">
          <template v-if="dataList.length <= 0">
            <el-empty :image-size="60" style="margin: 0 auto;" />
          </template>
          <template v-else>
            <resource ref="resourceRef" v-model="dataList" @node-click="handleClick" @node-dblclick="handleDblclick"
              @node-change="onNodeChange" @contextMenu="onContextMenu" @close-edit="onCloseEdit" />
          </template>
        </el-container>
        <el-aside width="400px">
          <Description :resource="selected" />
        </el-aside>
      </el-container>
    </el-container>

    <el-image-viewer v-if="showImage" :url-list="imageList" @close="showImage = false" />
    <FileTransfer ref="transferRef" v-model="uploadState.show" :folder="currentNode.id"
      @on-upload-complete="onUploadComplete" @on-before-close="onBeforeClose">
    </FileTransfer>
  </div>
</template>

<script setup>
import hotkeys from 'hotkeys-js';
import ContextMenu from '@imengyu/vue3-context-menu'
import FileTransfer from "./components/fileTransfer.vue"
import Resource from "./components/resource.vue"
import Description from "./components/description.vue"
import { ref, reactive, onMounted } from "vue";
import { delFolder, addFolder, getFolderContents, renameFolder, getFolderSubcontents } from "@/api/system/folder.js";
import { delFileResource, renameFileResource } from "@/api/system/fileresource.js";
const { proxy } = getCurrentInstance()


//弹窗操作类型
//0:新增，1：修改，2:查看
const isDragging = ref(false)
const showImage = ref(false);
const imageList = ref([]);
//表单ref
const transferRef = ref();
const resourceRef = ref([]);
// 遮罩层
const loading = ref(true);


// 当前选中文件或文件夹
const selected = ref();
//当前活跃文件或文件夹
const actived = ref();

//全局查找
const isSearch = ref(false);

//当前路径节点
const nodes = ref([]);
nodes.value.push({ name: "根目录" });
//当前目录节点
const currentNode = computed(() => {
  return nodes.value.at(-1);
})

// 总条数
const total = ref(0);
// 数据集
const dataList = ref([]);
// 查询参数
const queryParams = reactive({
  pageIndex: 1,
  pageSize: 10,
  folderId: undefined,
  keyword: undefined,
});
const uploadState = reactive({
  show: false,
  uploading: false,
  title: "文件上传",
  data: {
    folder: undefined,
  }
})


const contextMenuState = reactive({
  theme: "default dark",
  x: undefined,
  y: undefined,
  items: [
    {
      label: '打开',
      onClick: () => {
        handleDblclick(selected.value)
      }
    },
    {
      label: '上传文件',
      onClick: () => {
        uploadFile();
      }
    },
    {
      label: '新建文件夹',
      onClick: () => {
        handleAppendFolder();
      }
    },
    {
      label: '删除',
      shortcut: "Del",
      onClick: () => {
        handleDelete(selected.value);
      }
    },
    {
      label: '重命名',
      shortcut: "F2",
      onClick: () => {
        handleRename();
      }
    },
    {
      label: '刷新',
      shortcut: "F5",
      onClick: () => {
        handleRefresh();
      }
    },
    {
      label: "属性",
    }
  ],
})

const onContextMenu = (e, item) => {
  e.preventDefault();
  if (item) {
    selected.value = item;
    contextMenuState.items[0].hidden = false;
    contextMenuState.items[1].hidden = true;
    contextMenuState.items[2].hidden = true;
    contextMenuState.items[3].disabled = !proxy.$auth.hasFeature('folder:del');
    contextMenuState.items[4].hidden = false
  } else {
    selected.value = undefined;
    contextMenuState.items[0].hidden = true;
    contextMenuState.items[1].hidden = Boolean(currentNode.id);
    contextMenuState.items[1].disabled = !proxy.$auth.hasFeature('fileresource:upload')
    contextMenuState.items[2].hidden = false;
    contextMenuState.items[2].disabled = !proxy.$auth.hasFeature('folder:add');
    contextMenuState.items[3].disabled = true;
    contextMenuState.items[4].hidden = true
  }
  contextMenuState.x = e.x;
  contextMenuState.y = e.y;

  ContextMenu.showContextMenu(contextMenuState)
}

const onCloseEdit = (node, name, haschange) => {
  let func = node.isFolder ? renameFolder : renameFileResource;
  if (haschange) {
    let oldName = node.name;
    node.name = name;
    if (!name || name.trim() === '') {
      proxy.$modal.msgWarning("名称不能为空");
      node.name = oldName;
      return;
    }
    let data = { ...node, name: name };
    func(data).catch(() => {
      node.name = oldName;
    })
  }

}

// 获取列表方法
const getList = () => {
  loading.value = true;
  getFolderContents(queryParams).then((response) => {
    dataList.value = response.content;
    nodes.value = response.path;
    loading.value = false;
  });
};

// 重置表单
const reset = () => {

};

// 搜索按钮操作
const handleQuery = () => {
  queryParams.pageIndex = 1;
  getList();
};

//全局查找
const handleAllSearch = () => {
  if (!queryParams.keyword || queryParams.keyword.trim() === '') {
    proxy.$modal.msgWarning("请输入名称");
    return;
  }
  isSearch.value = true;
  loading.value = true;
  if (!currentNode.value.virtual) {
    let node = { name: `"${currentNode.value.name}"中的搜索结果`, virtual: true }
    nodes.value.push(node);
  }
  getFolderSubcontents(queryParams).then((res) => {
    dataList.value = res;
  }).finally(() => {
    loading.value = false;
  })
}

// 重置按钮操作
const resetQuery = () => {
  reset();
  handleQuery();
};


// 提交按钮
const uploadFile = () => {
  if (!currentNode.value.id) {
    proxy.$modal.msgWarning("根目录禁止上传文件")
    return;
  }
  uploadState.show = true;
};

//选中当前文件资源
const handleClick = (item, index) => {
  selected.value = item;
}


//双击事件
const handleDblclick = (item, index) => {
  switch (item.type) {
    case 'folder':
      selected.value = undefined;
      queryParams.folderId = item.id;
      handleQuery();
      break;
    case 'image':
      handleShowImage(item);
      break;
    default:
      proxy.$modal.msgWarning(`暂不支持预览${item.type}类型文件`);
      break;
  }
}

//图片展示
const handleShowImage = (image) => {
  showImage.value = true;
  imageList.value = [image.url];
}

//节点点击事件
const handleNodeClick = (node) => {
  let index = nodes.value.findIndex(n => n.id == node.id);
  if (index > -1) {
    nodes.value = nodes.value.slice(0, index + 1);
  }
  queryParams.folderId = node.id;
  queryParams.keyword = undefined;
  handleQuery();
}

//新建文件夹
const handleAppendFolder = () => {
  loading.value = true;
  let lastNode = nodes.value.at(-1);
  console.log(lastNode);
  let folder = {
    pid: lastNode?.id
  }
  addFolder(folder).then(res => {
    return handleQuery();
    // dataList.value.push({
    //   name: res.folderName,
    //   id: res.id,
    //   icon: 'folder',
    //   type: 'folder'
    // });
  }).then(() => {
    actived.value = res;
    selected.value = res;
  }).finally(res => {
    loading.value = false;
  })
}

//删除文件或者文件夹
const handleDelete = (item) => {
  if (!item) return;
  let msg = `确认删除【${item.name}】${item.type === 'folder' ? '文件夹及其内容' : '文件'}？`
  proxy.$modal.confirm(msg)
    .then(() => {
      const promise = item.type == 'folder'
        ? delFolder([item.id])
        : delFileResource([item.id]);
      return promise;
    })
    .then(() => {
      proxy.$modal.msgSuccess("删除成功");
      handleQuery();
    })
    .catch(() => { });
}

//重命名
const handleRename = () => {
  if (!selected.value)
    return;
  else {
    resourceRef.value.setRename(selected.value)
  }
}

//选中文件发生变化触发
const onNodeChange = (current, old) => {
  selected.value = current;
}


//刷新当前文件夹
const handleRefresh = () => {
  handleQuery();
}


const onDragEnter = () => {
  isDragging.value = true;
};

const onDragOver = (event) => {
  event.dataTransfer.dropEffect = "copy"; // 让鼠标显示“复制”样式
};

const onDragLeave = () => {
  isDragging.value = false;
};

const onDrop = (event) => {
  isDragging.value = false;
  const files = event.dataTransfer.files; // 获取拖拽的文件
  if (files.length > 5) {
    proxy.$modal.msgWarning("最多上传5个文件")
    return;
  }

  uploadState.show = true;
  nextTick(() => {
    if (transferRef.value) {
      transferRef.value.appendFile(files);
    } else {
      console.error('No transferRef');
      return;
    }
  })
};

const onUploadComplete = (response, uploadFile) => {
  console.log(response);
  let resource = {
    name: response.fileName,
    id: response.id,
    icon: response.icon,
    type: response.type
  }
  dataList.value.push(resource)
}

const onBeforeClose = () => {
  handleQuery();
}


// 页面加载时调用获取列表方法
onActivated(() => {
  hotkeys('F5', (event) => {
    event.preventDefault();
    handleQuery();
  })
  hotkeys('Delete', (event) => {
    event.preventDefault();
    if (selected.value) {
      handleDelete(selected.value)
    }
  })
  hotkeys('F2', (event) => {
    event.preventDefault();
    handleRename();
  })
})

onDeactivated(() => {
  hotkeys.unbind('F5');
  hotkeys.unbind('F2');
  hotkeys.unbind('Delete');
})

onMounted(() => {
  resetQuery();
})



</script>

<style lang="scss" scoped>
.app-container {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
}

.header-wrapper {
  display: flex;
  background-color: var(--el-border-color-extra-light);
  align-items: center;

  .breadcrumb {
    flex: 1;
  }

  .input {
    flex: 0;
    flex-basis: 240px;
  }
}

.content-wrapper {
  padding-top: 10px;
}
</style>
